useEffect


Many times, we want to run some additional code after React has updated the DOM.

That code can be getting the Data by Calling a Web API or Setting up subscriptions or writing the logs after the DOM is ready. 

If we want to write such additional code in Class Components, we have lifecycle methods like componentDidMount, componentDidUpdate methods. 

What if, if want to write such code in the case of function components.

Lets Open index.js file from our demo-project. 

Lets create EmployeeReports Component using which we display the list of Employees by fetching it from API.

We know how to send a Web API request and get the data from our React Application. But now question is where should we write the code. 

Remember that we want to execute that code after DOM is ready. 

If we think of writing just before our return statement, just lets do one thing. We will write a console log here which shows us the DOM status. 

console.log(document.readyState);

Call our Employee Reports Component and render that to our root container. 

At this point of time, our table will be empty without data because we are yet to send the Web API request to get the data. 

Save the changes, navigate to the browser. 

We can see the table but no data. Lets open developer tools, we can see the status. It says that loading. 

That means we should not be writing the Code here. 

So where should we write the code which should get executed after our DOM is ready. 

This is where we will make use of another hook in React called as useEffect

useEffect is a function that runs when the component is first rendered, and on every subsequent re-render/update.

We can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

Lets call useEffect function and it takes one callback function as a parameter. 

We will write one arrow function. Inside that function, lets place the same console.log statement we have written earlier. Save the changes, navigate to the browser. 

Open developer tools and we can see that the status is Complete. 

Our DOM is ready and we can do all the other operations we want now. 

Lets go back to Visual studio code, now within this useEffect, lets place the code using which we will send the API request. We have discussed this already in our previous sessions. I am pasting that code here. When we get the response from our Web API, we will call our setEmployees function and we will pass the list to that. 

Save the changes, navigate to the browser. We can see that employee details are being displayed here. 

When the DOM is ready, we are sending the API request, getting the employees data and updating our employees state variable by calling setEmployees method. But this has a Problem. Remember that when there is any change in the properties data or state data of a component, then that component gets re-rendered. 

Resulting our useEffect function gets called again. It will send an API request, get the data and assign it to employees state variable. That will make the component gets re-rendered and it will go into infinite loop. 

Lets add an alert. Save the changes, navigate to the browser. We can see that we get the alert again and again. 

If you want to run an effect only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run.

import ReactDOM from "react-dom";
import React, { Component, useState, useEffect } from "react";

function EmployeeComponent(){
  const [employees,setEmployees]=useState([]);

  useEffect(()=>{
    alert('We are in useEffect function');
    fetch("https://localhost:44306/api/Employee")
      .then(res => res.json())
      .then(
        (result) => {
          setEmployees(result);
        }
      );
  },[]);
  
  return(
    <div>
      <h2>Employees Data...</h2>
      <table>
        <thead>
          <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Location</th>
            <th>Salary</th>
          </tr>
        </thead>
        <tbody>
          {employees.map(emp=>(
            <tr key={emp.Id}>
              <td>{emp.Id}</td>
              <td>{emp.Name}</td>
              <td>{emp.Location}</td>
              <td>{emp.Salary}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

const element=<EmployeeComponent></EmployeeComponent>

ReactDOM.render(element,document.getElementById("root"));

Video Reference:





© 2020 Pragimtech. All Rights Reserved.